Skip to content

fix #23262 - [REG v2.113.0-beta.1] ICE when trying to cast a class instance to a C++ interface - #23263

Open
rainers wants to merge 2 commits into
dlang:stablefrom
rainers:issue_23262
Open

fix #23262 - [REG v2.113.0-beta.1] ICE when trying to cast a class instance to a C++ interface#23263
rainers wants to merge 2 commits into
dlang:stablefrom
rainers:issue_23262

Conversation

@rainers

@rainers rainers commented Jun 14, 2026

Copy link
Copy Markdown
Member

no need to exclude C++ classes/interfaces from runtime cast target

…ss instance to a C++ interface

no need to exclude C++ classes/interfaces from runtime cast target
@dlang-bot

Copy link
Copy Markdown

Thanks for your pull request, @rainers!

Bugzilla references

Your PR doesn't reference any Bugzilla issue.

If your PR contains non-trivial changes, please reference a Bugzilla issue or create a manual changelog.

⚠️⚠️⚠️ Warnings ⚠️⚠️⚠️

  • In preparation for migrating from Bugzilla to GitHub Issues, the issue reference syntax has changed. Please add the word "Bugzilla" to issue references. For example, Fix Bugzilla Issue 12345 or Fix Bugzilla 12345.(Reminder: the edit needs to be done in the Git commit message, not the GitHub pull request.)

Testing this PR locally

If you don't have a local development environment setup, you can use Digger to test this PR:

dub run digger -- build "stable + dmd#23263"

Comment thread compiler/test/runnable/casting.d
Comment thread compiler/src/dmd/expressionsem.d Outdated
Comment thread compiler/test/runnable/casting.d Outdated
@rainers

rainers commented Jul 23, 2026

Copy link
Copy Markdown
Member Author

@ibuclaw I think I covered your concerns. Still any objections?

@kinke

kinke commented Jul 31, 2026

Copy link
Copy Markdown
Contributor

I hope you don't need to deal with/break ClassKind.objc stuff.

@rainers

rainers commented Aug 2, 2026

Copy link
Copy Markdown
Member Author

I hope you don't need to deal with/break ClassKind.objc stuff.

dmd crashes when cross-compiling for macos, but I tried LDC on

void main()
{
    Object obj = new Object;
    auto objc = cast(ObjectiveC)(obj);
    auto nsstring = cast(NSString)(obj);
    auto objc2 = cast(ObjectiveC)(nsstring);
    auto obj2 = cast(Object)(nsstring);
}

extern (Objective-C)
extern interface NSString
{
    import core.attribute : selector;
    const(char)* UTF8String() @selector("UTF8String");
}

extern (Objective-C) class ObjectiveC {}

class classObjC2D : ObjectiveC, NSString
{
    extern (Objective-C)
    override const(char)* UTF8String() { return null; }
}

[casting between extern(C++) and extern(Objective-C) doesn't seem supported.]

LDC 1.42 generates calls to _d_cast for all assignments in main, but with LDC 1.41 objc_opt_isKindOfClass, objc_opt_isKindOfClass, object_getClass, class_conformsToProtocol and _d_interface_cast get called. Is this a regression?

It still seems this PR might indeed change what LDC does for extern(Objective-C) <-> extern(D) casts.
Does LDC actually support a cast from extern(Objective-C) to extern(D)?

I'm inclined to remove the restriction that the dynamic cast is only used for D -> D/C++, but allow any target interface, no matter what linkage.

@kinke

kinke commented Aug 2, 2026

Copy link
Copy Markdown
Contributor

Is this a regression?

I guess so, although I'm not aware of any filed issues - our extra glue code for that is still in place, but we expect these casts NOT to be lowered to _d_cast (and druntime doesn't use objc_opt_isKindOfClass etc. in that hook or anywhere else).

Edit: Or maybe that was/is just an overshooting implementation in LDC, and relying on the D declarations incl. _d_cast() enough.

Edit2: Some minimal context in https://github.com/ldc-developers/ldc/pull/4777/changes#r1863875351. I guess this was added to support Swift class/interface stubs (so I guess incomplete/opaque bindings on the D side). But I guess this could all be handled in _d_cast in druntime nowadays instead (and then not just LDC-specific).

I'm inclined to remove the restriction that the dynamic cast is only used for D -> D/C++, but allow any target interface, no matter what linkage.

Yeah I think that makes sense.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

5 participants